var iot = require('iot');
var http = require('http');
var fs = require('fs');
var player = require('audioplayer');

const productkey = '';
const devicename = '';
const devicesecret = '';

var toneDir = "/";
var tonenameSuffix = [".wav", ".mp3"];

var tonenameNumb = ["tone_0", "tone_1", "tone_2", "tone_3", "tone_4", "tone_5", "tone_6", "tone_7", "tone_8", "tone_9"];
var tonenameNumb1 = "tone_1";
var tonenameUnit = ["none", "tone_S", "tone_B", "tone_K"];
var tonenameHunit = ["tone_W", "none"];

player.setVolume(6);

var iotdev = iot.device({
  productKey: productkey,
  deviceName: devicename,
  deviceSecret: devicesecret,
  success: function() {
    console.log('success connect to aliyun iot server');
  },
  fail: function() {
    console.log('fail to connect to aliyun iot server');
  }
});

function voiceboxAddAmount(amount, toneList, toneIndex, formatFlag)
{
  var numb = parseInt(amount);
  var deci = amount - numb;
  var target = numb;
  var subTarget;
  var subNumber;
  var slot;
  var factor;
  var count = 0;
  var prevSlotZero = false;
  var hundredMillionExist = false;
  var tenThousandExist = false;

  if (numb < 0 || numb >= 1000000000000) {
    console.log('amount overrange');
    return toneIndex;
  }

  deci = deci.toFixed(4);
  if (deci < 0.0001 && deci > 0.0) {
    deci = 0.0001;
  }

  for (var i = 2; i >= 0; i--) {
    factor = Math.pow(10000, i);
    if (target < factor) {
      continue;
    }

    subTarget = parseInt(target / factor);
    target %= factor;
    if (subTarget == 0) {
      continue;
    }

    if (i == 2) {
      hundredMillionExist = true;
    } else if (i == 1) {
      tenThousandExist = true;
    }

    subNumber = subTarget;
    prevSlotZero = false;

    for (var depth = 3; depth >= 0; depth--) {
      if (subNumber == 0) {
        break;
      }
      factor = Math.pow(10, depth);

      if ((hundredMillionExist == true || tenThousandExist == true) && i == 0) {
      } else if (hundredMillionExist == true && tenThousandExist == true && depth > 0 && subTarget < factor) {
      } else if (subTarget < factor) {
        continue;
      }

      slot = parseInt(subNumber / factor);
      subNumber %= factor;
      if (slot == 0 && depth == 0) {
        continue;
      }

      if ((subTarget < 20 && depth == 1) || (slot == 0 && prevSlotZero) || (slot == 0 && depth == 0)) {
      } else {
        toneList[toneIndex++] = toneDir + tonenameNumb[slot] + tonenameSuffix[formatFlag];
        count++;
        if (slot == 0 && prevSlotZero == false) {
          prevSlotZero = true;
        } else if (prevSlotZero == true && slot != 0) {
          prevSlotZero = false;
        }
      }

      if (slot > 0 && depth > 0) {
        toneList[toneIndex++] = toneDir + tonenameUnit[depth] + tonenameSuffix[formatFlag];
        count++;
      }
    }

    if (i > 0) {
      toneList[toneIndex++] = toneDir + tonenameHunit[i - 1] + tonenameSuffix[formatFlag];
      count++;
    }
  }

  if (count == 0 && numb == 0) {
    toneList[toneIndex++] = toneDir + tonenameNumb[0] + tonenameSuffix[formatFlag];
  }

  if (deci >= 0.0001) {
    toneList[toneIndex++] = toneDir + "tone_dot" + tonenameSuffix[formatFlag];
    var deciString = deci.toString();
    deciString = deciString.substring(2);
    var deciArray = deciString.split('');

    for (var deciIndex = deciArray.length - 1; deciIndex >= 0; deciIndex--) {
      if (deciArray[deciIndex] != '0') {
        break;
      }
      delete deciArray[deciIndex];
    }

    deciArray.forEach(function(item) {
      if (item >= '0' && item <= '9') {
        toneList[toneIndex++] = toneDir + tonenameNumb[item - '0'] + tonenameSuffix[formatFlag];
      }
    });
  }
  return toneIndex;
}

var receiptToneList = new Array();

function voiceboxPlayReceipt(receipt)
{
  var receipt = eval('(' + receipt + ')');
  var msgArray = receipt.speechs;
  var toneIndex = 0;

  var audioResFormat = 0;
  if (receipt.format == 'mp3') {
  	audioResFormat = 1;
  }

  receiptToneList.splice(0, receiptToneList.length);

  for (var msgIndex = 0; msgIndex < msgArray.length; msgIndex++) {
    var msg = msgArray[msgIndex];
    if (msg.charAt(0) == '{') {
      if (msg.length > 3 && msg.charAt(msg.length - 1) == '}') {
        if (msg.charAt(1) == '$') {
          var amount = parseFloat(msg.substring(2, msg.length - 1));
          toneIndex = voiceboxAddAmount(amount, receiptToneList, toneIndex, audioResFormat);
          receiptToneList[toneIndex++] = toneDir + "tone_Y" + tonenameSuffix[audioResFormat];
        } else if (msg.charAt(1) == 'N' || msg.charAt(1) == 'n') {
          var msgNum = msg.substring(2, msg.length - 1);
          if (!isNaN(msgNum)) {
            var numArray = msgNum.split('');
            for (var numIndex = 0; numIndex < numArray.length; numIndex++) {
              if (numArray[numIndex] >= '0' && numArray[numIndex] <= '9') {
                receiptToneList[toneIndex++] = toneDir + "tone_" + numArray[numIndex].toString() + tonenameSuffix[audioResFormat];
              }
            }
          }
        } else if (msg.charAt(1) == 'T' || msg.charAt(1) == 't') {
          var msgNum = msg.substring(2, msg.length - 1);
          if (!isNaN(msgNum)) {
            var numArray = msgNum.split('');
            for (var numIndex = 0; numIndex < numArray.length; numIndex++) {
              if (numArray[numIndex] >= '0' && numArray[numIndex] <= '9') {
                if (numArray[numIndex] == '1') {
                  receiptToneList[toneIndex++] = toneDir + tonenameNumb1 + tonenameSuffix[audioResFormat];
                } else {
                  receiptToneList[toneIndex++] = toneDir + "tone_" + numArray[numIndex].toString() + tonenameSuffix[audioResFormat];
                }
              }
            }
          }
        } else {
          console.log('unknown speech ' + msg);
        }
      } else {
        console.log('unknown speech ' + msg);
      }
    } else {
      receiptToneList[toneIndex++] = toneDir + msg + tonenameSuffix[audioResFormat];
    }
  }
  console.log('play list ' + receiptToneList);
  player.listPlay(receiptToneList);
}

function voiceboxPlayContent(content)
{
  var content = eval('(' + content + ')');
  player.play(content.url);
}

var resDownloading = 0;

function voiceboxResDownload(filepath, jobcode)
{
  var fileContent = fs.readSync(filepath);
  var resContent = eval('(' + fileContent + ')');
  
  var speechArray = resContent.audios;
  
  var audioResFormat = 0;

  if (resContent.format == 'mp3') {
  	audioResFormat = 1;
  }

  console.log('update local speech jobcode: ' + jobcode);
  for (var speechIndex = 0; speechIndex < speechArray.length; speechIndex++) {
    var speech = speechArray[speechIndex];
    console.log('update local speech id: ' + speech.id + ', url: ' + speech.url);
    var resourcePath = toneDir + speech.id + tonenameSuffix[audioResFormat];
    http.addDownload({
        url: speech.url,
        filepath: resourcePath,
        method: 'GET',
        headers: {
          'Accept':'*/*',
        }
    });
  }
  http.startDownload({
    success: function (data) {
      console.log('amp http download result ' + data);
      resDownloading = 0;
      if (data == 0) {
        console.log('amp http: [success] http.download');
        iotdev.postEvent({
          id: 'SpeechUpdateResponse',
          params: {
            jobcode: jobcode,
            result: data
          },
          success: function () {
            console.log('amp iot: [success] iot.postEvent');
          },
          fail: function () {
            console.log('amp iot: [failed] iot.postEvent');
          }
        });
      } else {
        console.log('amp http: [failed] http.download');
        iotdev.postEvent({
          id: 'SpeechUpdateResponse',
          params: {
            jobcode: jobcode,
            result: data
          },
          success: function () {
            console.log('iot: [success] iot.postEvent');
          },
          fail: function () {
            console.log('iot: [failed] iot.postEvent');
          }
        });
      }
    }
  });
}

function voiceboxResUpdate(resource)
{
  var resource = eval('(' + resource + ')');
  
  if (resDownloading == 1) {
  	console.log('res downloading, post result 3');
  	var resultData = 3;
    iotdev.postEvent({
      id: 'SpeechUpdateResponse',
      params: {
        jobcode: resource.jobcode,
        result: resultData
      },
      success: function () {
        console.log('iot: [success] iot.postEvent');
      },
      fail: function () {
        console.log('iot: [failed] iot.postEvent');
      }
    });
    return;
  }

  resDownloading = 1;
  http.addDownload({
    url: resource.url,
    filepath: "/temp.txt",
    method: 'GET',
    headers: {
      'Accept':'*/*',
    }
  });
  http.startDownload({
    success: function (data) {
      console.log('http download result ' + data);
      if (data == 0) {
        console.log('http: [success] http.download');
        voiceboxResDownload("U:/temp.txt", resource.jobcode);
      } else {
        console.log('http: [failed] http.download');
        resDownloading = 0;
        iotdev.postEvent({
          id: 'SpeechUpdateResponse',
          params: {
            jobcode: resource.jobcode,
            result: data
          },
          success: function () {
            console.log('iot: [success] iot.postEvent');
          },
          fail: function () {
            console.log('iot: [failed] iot.postEvent');
          }
        });
      }
    }
  });
}

iotdev.on('close', function() {
  console.log('iot close');
});

iotdev.on('error', function(data) {
  console.log('error ' + data);
});

iotdev.on('props', function(request_len, request) {
  console.log('received cloud request len is ' + request_len);
  console.log('received cloud request is ' + request);
});

iotdev.on('service', function(serviceid, request) {
  if (serviceid.indexOf("AudioPlayback") != -1) {
    voiceboxPlayContent(request);
  } else if (serviceid.indexOf("SpeechBroadcast") != -1) {
    voiceboxPlayReceipt(request);
  } else if (serviceid.indexOf("SpeechPost") != -1) {
  	voiceboxResUpdate(request);
  }
});
